package server

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/doujunyu/gogo/gogo_log"
	"github.com/doujunyu/gogo/sql_aid"
	"go_self/model"
	"go_self/util"
	"strconv"
	"time"
)

// OrderBySkuJsonToData 预定订单详情 skuJson参数结构 [{"sku_id":"222","number":"10"},{"sku_id":"223","number":"20"}]
func OrderBySkuJsonToData(skuJson string) (map[string]interface{}, error) {
	skuDataArr := make([]map[string]interface{}, 0, 0)
	err := json.Unmarshal([]byte(skuJson), &skuDataArr)
	if err != nil {
		return nil, errors.New("skuJson数据解析错误")
	}

	//根据sku_id获取sku详情
	skuIds := util.ArrayField(&skuDataArr, "sku_id")
	skuSql, args := sql_aid.PgTable(model.TableByGoodsSku).WhereIn("id", *skuIds...).ToSql()
	skuData, err := sql_aid.DataToMap(model.PgSql.Query(skuSql, args...))
	if err != nil {
		return nil, errors.New("sku错误")
	}
	//获取商品信息
	skuGoodsIds := util.ArrayField(&skuData, "goods_id")
	goodsSql, args := sql_aid.PgTable(model.TableByGoods).Field("id", "shop_id", "title", "status").WhereIn("id", *skuGoodsIds...).ToSql()
	goodsData, err := sql_aid.DataToMap(model.PgSql.Query(goodsSql, args...))
	if err != nil {
		return nil, errors.New("获取商品信息处理错误")
	}
	goodsDataColumnId := util.ArrayColumnByInt64(&goodsData, "id") //商品表中的ID做下标
	//获取店铺信息
	skuShopIds := util.ArrayField(&skuData, "shop_id")
	shopSql, args := sql_aid.PgTable(model.TableByShop).Field("id", "title", "logo", "status").WhereIn("id", *skuShopIds...).ToSql()
	shopData, err := sql_aid.DataToMap(model.PgSql.Query(shopSql, args...))
	if err != nil {
		return nil, errors.New("获取店铺信息处理错误")
	}

	//计算数据
	skuKeyIds := util.ArrayColumnByInt64(&skuData, "id") //sku表中的ID做下标
	var priceAll = 0.00
	var goodsCount = 0
	for _, val := range skuDataArr { //接收的json数据做循环
		goodsCount++
		setSkuData := skuKeyIds[int64(val["sku_id"].(float64))]
		if setSkuData == nil {
			return nil, errors.New("数据错误")
		}
		if int64(val["number"].(float64)) > setSkuData["number"].(int64) { //判断购买的商品是否超出商品的实际数量
			goodsTitle := goodsDataColumnId[setSkuData["goods_id"].(int64)]["title"].(string)
			goodsSkuNumber := setSkuData["number"].(int64)
			return nil, errors.New(fmt.Sprintf("规格是'%v'的'%v'仅剩余%v件", setSkuData["sku_string"], goodsTitle, goodsSkuNumber))
		}
		priceAll += util.StringToFloat64(setSkuData["price"].(string)) * val["number"].(float64) //价格 = sku中的价格 * 要购买的数量
	}
	priceAll, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", priceAll), 64)

	//sku信息中组装商品信息 且 购买数量组装
	skuIdByNumber := util.ArrayColumnByFloat64(&skuDataArr, "sku_id")
	skuDataList := make([]map[string]interface{}, 0, 0)
	for _, skuVal := range skuData {
		set := make(map[string]interface{})
		set["shop_id"] = skuVal["shop_id"]
		set["sku"] = skuVal
		goodsOnly := goodsDataColumnId[skuVal["goods_id"].(int64)]
		if goodsOnly != nil {
			set["goods"] = goodsOnly
		} else {
			return nil, errors.New("有商品不存在")
		}

		//商品库存组装
		skuNumber := skuIdByNumber[float64(skuVal["id"].(int64))]["number"]
		set["number"] = skuNumber
		if skuNumber != nil {
			skuVal["number_pay"] = skuNumber
			//判断商品数量库存
			if int64(skuNumber.(float64)) > skuVal["number"].(int64) {
				return nil, errors.New(goodsOnly["title"].(string) + "中" + skuVal["sku_string"].(string) + "超出剩余库存")
			}
		} else {
			skuVal["number_pay"] = float64(1)
			if skuVal["number"].(int64) < 1 {
				return nil, errors.New(goodsOnly["title"].(string) + "中" + skuVal["sku_string"].(string) + "超出剩余库存")
			}
		}
		skuDataList = append(skuDataList, set)
	}
	//sku根据店铺分组
	skuGroupData := util.ArrayColumnGroupByInt64(&skuDataList, "shop_id")
	//店铺信息中组装sku分组后的信息
	for _, shopVal := range shopData {
		if skuGroupData[shopVal["id"].(int64)] != nil {
			shopVal["sku_data"] = skuGroupData[shopVal["id"].(int64)]
		}
	}
	data := make(map[string]interface{})
	data["data"] = shopData
	data["price_all"] = priceAll
	data["goods_count"] = goodsCount

	return data, nil
}

// OrderByCreateOrder 生成订单 skuJson参数结构 [{"sku_id":"222","number":"10"},{"sku_id":"223","number":"20"}]
func OrderByCreateOrder(userId int64, input map[string]string) (map[string]interface{}, error) {
	if input["sku_json"] == "" || input["address_user"] == "" || input["address_mobile"] == "" || input["address_info"] == "" || input["pay_type"] == "" {
		return nil, errors.New("缺少参数")
	}
	skuDataArr := make([]map[string]interface{}, 0, 0)
	err := json.Unmarshal([]byte(input["sku_json"]), &skuDataArr)
	if err != nil {
		return nil, errors.New("skuJson数据解析错误")
	}
	//用户购物车数据
	shoppingCartSql, args := sql_aid.PgTable(model.TableByUserShoppingCart).Where("user_id  = ?", userId).ToSql()
	shoppingCartData, err := sql_aid.DataToMap(model.PgSql.Query(shoppingCartSql, args...))
	if err != nil {
		return nil, errors.New("内部错误")
	}
	shoppingCartDataById := util.ArrayColumnByInt64(&shoppingCartData, "goods_sku_id")

	//根据sku_id获取sku详情
	skuIds := util.ArrayField(&skuDataArr, "sku_id")
	skuSql, args := sql_aid.PgTable(model.TableByGoodsSku).WhereIn("id", *skuIds...).ToSql()
	skuData, err := sql_aid.DataToMap(model.PgSql.Query(skuSql, args...))
	if err != nil {
		return nil, errors.New("sku错误")
	}

	var OrderBypriceAll float64
	orderChildData := make([]map[string]interface{}, 0, 0)
	skuDataByInt64 := util.ArrayColumnByInt64(&skuData, "id")
	for _, val := range skuDataArr { //检查商品是否可以下单
		skuDataSet := skuDataByInt64[int64(val["sku_id"].(float64))]
		if skuDataSet == nil {
			return nil, errors.New(fmt.Sprintf("ID为%v的规格数据不存在", val["sku_id"]))
		}

		if int(skuDataSet["is_up_down"].(int64)) != model.GoodsSkuByIsUpDownYes {
			return nil, errors.New(fmt.Sprintf("ID为%v的规格下架了", val["sku_id"]))
		}
		if skuDataSet["number"].(int64) < int64(val["number"].(float64)) {
			return nil, errors.New(fmt.Sprintf("ID为%v的规格库存不足%v个", val["sku_id"], val["number"]))
		}
		//进行组装数据
		orderChildDataOnly := make(map[string]interface{})
		//orderChildDataOnly["order_id"] = orderId
		orderChildDataOnly["user_id"] = userId
		orderChildDataOnly["shop_id"] = skuDataSet["shop_id"]
		orderChildDataOnly["goods_id"] = skuDataSet["goods_id"]
		orderChildDataOnly["goods_sku_id"] = skuDataSet["id"]
		orderChildDataOnly["goods_sku_number"] = int64(val["number"].(float64))
		priceAll := util.StringToFloat64(skuDataSet["price"].(string)) * val["number"].(float64)
		OrderBypriceAll += priceAll
		orderChildDataOnly["price_all"] = priceAll
		orderChildDataOnly["status"] = model.OrderChildByStatusPay
		orderChildDataOnly["address_user"] = input["address_user"]
		orderChildDataOnly["address_mobile"] = input["address_mobile"]
		orderChildDataOnly["address_info"] = input["address_info"]
		orderChildDataOnly["goods_sku_price"] = skuDataByInt64[int64(val["sku_id"].(float64))]["price"]
		orderChildDataOnly["order_no"] = util.OrderNo("order_child_")
		orderChildData = append(orderChildData, orderChildDataOnly)
	}
	//时间
	thisTime := time.Now().Format(time.RFC3339)
	//进行添加数据
	tx, _ := model.PgSql.Begin()
	defer tx.Rollback()
	var orderId int64
	//主订单数据
	orderMapData := make(map[string]interface{})
	orderMapData["order_no"] = util.OrderNo("order_")
	orderMapData["user_id"] = userId
	orderMapData["price_all"] = OrderBypriceAll
	orderMapData["price_true"] = 0.00
	//orderMapData["price_time"] = thisTime
	orderMapData["pay_type"] = input["pay_type"]
	orderMapData["time_c"] = thisTime
	orderMapData["time_u"] = thisTime
	orderSql, args := sql_aid.PgTable(model.TableByOrder).InsertByMap(&orderMapData)
	err = tx.QueryRow(orderSql+" RETURNING id", args...).Scan(&orderId)
	if err != nil {
		gogo_log.Error("server_OrderByCreateOrder", "主订单添加失败", err.Error())
		return nil, errors.New("下单失败")
	}
	for _, val := range orderChildData {
		//子订单录入
		val["order_id"] = orderId
		orderChildSql, args := sql_aid.PgTable(model.TableByOrderChild).InsertByMap(&val)
		_, err = tx.Exec(orderChildSql, args...)
		if err != nil {
			gogo_log.Error("server_OrderByCreateOrder", "子订单添加失败", err.Error())
			return nil, errors.New("下单失败1")
		}
		//对应购物车去除
		shoppingCartOnly := shoppingCartDataById[val["goods_sku_id"].(int64)] //找到对应的购物车数据

		if shoppingCartOnly != nil && (shoppingCartOnly["number"].(int64)-val["goods_sku_number"].(int64)) > 0 {

			updateShoppingCartOnly := make(map[string]interface{})
			shoppingCartSql, args := sql_aid.PgTable(model.TableByUserShoppingCart).Where("id = ?", shoppingCartOnly["id"]).Where("user_id = ?", userId).Dec("number", val["goods_sku_number"]).UpdateByMap(&updateShoppingCartOnly)
			_, err = tx.Exec(shoppingCartSql, args...)
			if err != nil {
				gogo_log.Error("server_OrderByCreateOrder", "购物车减商品数量失败", err.Error())
				return nil, errors.New("下单失败2")
			}
		}
		if shoppingCartOnly != nil && (shoppingCartOnly["number"].(int64)-val["goods_sku_number"].(int64)) <= 0 {

			shoppingCartSql, args := sql_aid.PgTable(model.TableByUserShoppingCart).Where("id = ?", shoppingCartOnly["id"]).Where("user_id = ?", userId).Delete()
			_, err = tx.Exec(shoppingCartSql, args...)
			if err != nil {
				gogo_log.Error("server_OrderByCreateOrder", "购物车删商品失败", err.Error())
				return nil, errors.New("下单失败3")
			}
		}
		//对应商品SKU减去商品
		updateGoodsSku := make(map[string]interface{})
		var updateNumber int64
		goodsSkuSql, args := sql_aid.PgTable(model.TableByGoodsSku).Where("id = ?", val["goods_sku_id"]).Dec("number", val["goods_sku_number"]).UpdateByMap(&updateGoodsSku)
		err = tx.QueryRow(goodsSkuSql+" RETURNING number", args...).Scan(&updateNumber)
		if err != nil {
			gogo_log.Error("server_OrderByCreateOrder", "商品删除失败", err.Error())
			return nil, errors.New("下单失败3")
		}
		if updateNumber < 0 {
			gogo_log.Error("server_OrderByCreateOrder", "商品删除失败", err.Error())
			return nil, errors.New(fmt.Sprintf("ID为%v的规格库存不足%v个", val["goods_sku_id"], val["number"]))
		}
	}
	tx.Commit()
	data := make(map[string]interface{})
	data["order_id"] = orderId
	data["pay_code"] = ""
	return data, nil
}

// OrderByList 订单列表
func OrderByList(input map[string]string) []map[string]interface{} {
	orderSql, args := sql_aid.PgTable(model.TableByOrderChild).WhereRaw(func(query *sql_aid.PgQuery, i ...interface{}) {
		if i[0].(map[string]string)["user_id"] != "" {
			query.Where("user_id = ?", i[0].(map[string]string)["user_id"])
		}
		//if i[0].(map[string]string)["shop_id"] != "" {
		//	query.Where("shop_id = ?", i[0].(map[string]string)["shop_id"])
		//}
		if i[0].(map[string]string)["status"] != "" {
			query.Where("status = ?", i[0].(map[string]string)["status"])
		}
	}, input).OrderBy("id desc").PageSize(input["page"], input["page_size"]).ToSql()
	orderData, err := sql_aid.DataToMap(model.PgSql.Query(orderSql, args...))
	if err != nil {
		gogo_log.Error("server_GoodsByList", "商品列表", err.Error())
		return []map[string]interface{}{}
	}
	//商品信息
	orderDataByGoodsId := util.ArrayField(&orderData, "goods_id")
	goodsSql, args := sql_aid.PgTable(model.TableByGoods).WhereIn("id", *orderDataByGoodsId...).ToSql()
	GoodsData, err := sql_aid.DataToMap(model.PgSql.Query(goodsSql, args...))
	goodsDataByID := util.ArrayColumnByInt64(&GoodsData, "id")

	//商品规格信息
	orderDataByGoodsSkuId := util.ArrayField(&orderData, "goods_sku_id")
	goodsSkuSql, args := sql_aid.PgTable(model.TableByGoodsSku).WhereIn("id", *orderDataByGoodsSkuId...).ToSql()
	GoodsSkuData, err := sql_aid.DataToMap(model.PgSql.Query(goodsSkuSql, args...))
	goodsSkuDataByID := util.ArrayColumnByInt64(&GoodsSkuData, "id")

	//商品规格信息
	orderDataByShopId := util.ArrayField(&orderData, "shop_id")
	shopSql, args := sql_aid.PgTable(model.TableByShop).WhereIn("id", *orderDataByShopId...).ToSql()
	shopData, err := sql_aid.DataToMap(model.PgSql.Query(shopSql, args...))
	shopDataByID := util.ArrayColumnByInt64(&shopData, "id")

	for _, val := range orderData {
		val["goods"] = goodsDataByID[val["goods_id"].(int64)]
		val["goods_sku"] = goodsSkuDataByID[val["goods_sku_id"].(int64)]
		val["shop"] = shopDataByID[val["shop_id"].(int64)]
	}
	return orderData

}

// OrderBySendGoods 订单发货，商家填写物流单号
func OrderBySendGoods(input map[string]string)error{
	if input["order_child_id"] == "" || input["logistics_no"] == "" || input["logistics_name"] == ""{
		return errors.New("缺少参数")
	}
	thisTime := time.Now().Format(time.RFC3339)
	orderUpdate := make(map[string]interface{})
	orderUpdate["status"] = model.OrderChildByStatusReceive
	orderUpdate["logistics_no"] = input["logistics_no"]
	orderUpdate["logistics_name"] = input["logistics_name"]
	orderUpdate["time_wait_receive"] = thisTime
	orderChildSql,args := sql_aid.PgTable(model.TableByOrderChild).WhereId(input["order_child_id"]).Where("status = ?",model.OrderChildByStatusSend).UpdateByMap(&orderUpdate)
	_,err := model.PgSql.Exec(orderChildSql,args...)
	if err != nil{
		gogo_log.Error("server_OrderBySendGoods","更新数据错误",err.Error())
		return errors.New("更改错误")
	}

	return nil
}

// OrderByToWaitDiscuss 订单确认收货
func OrderByToWaitDiscuss(userId int64, orderChildId int64) error {
	orderChildSql, arge := sql_aid.PgTable(model.TableByOrderChild).WhereId(orderChildId).ToSql()
	orderChildData, err := sql_aid.DataToMap(model.PgSql.Query(orderChildSql, arge...))
	if err != nil {
		gogo_log.Error("server_OrderByToWaitDiscuss", "数据错误", err.Error())
		return errors.New("数据错误")
	}
	if len(orderChildData) <= 0 {
		return errors.New("数据不存在")
	}
	if orderChildData[0]["user_id"].(int64) != userId {
		return errors.New("您无法对当前数据进行更改")
	}
	if orderChildData[0]["status"].(int64) != model.OrderChildByStatusReceive {
		return errors.New("状态无法改变")
	}
	//时间
	thisTime := time.Now().Format(time.RFC3339)
	OrderChildUpdate := make(map[string]interface{})
	OrderChildUpdate["status"] = model.OrderChildByStatusDiscuss
	OrderChildUpdate["time_wait_discuss"] = thisTime
	orderChildSqlUp, args := sql_aid.PgTable(model.TableByOrderChild).WhereId(orderChildId).UpdateByMap(&OrderChildUpdate)
	_, err = model.PgSql.Exec(orderChildSqlUp, args...)
	if err != nil {
		return errors.New("变更失败")
	}
	return nil

}

// OrderByToFinish 订单完成，用户评价之后进入的状态
func OrderByToFinish(userId int64,input map[string]string)error{
	if userId == 0 || input["order_child_id"] == "" {
		return errors.New("缺少参数")
	}
	orderChildSql, arge := sql_aid.PgTable(model.TableByOrderChild).WhereId(input["order_child_id"]).ToSql()
	orderChildData, err := sql_aid.DataToMap(model.PgSql.Query(orderChildSql, arge...))
	if err != nil {
		gogo_log.Error("server_OrderByToFinish", "数据错误", err.Error())
		return errors.New("数据错误")
	}
	if len(orderChildData) <= 0 {
		return errors.New("数据不存在")
	}
	if orderChildData[0]["user_id"].(int64) != userId {
		return errors.New("您无法对当前数据进行更改")
	}
	if orderChildData[0]["status"].(int64) != model.OrderChildByStatusDiscuss {
		return errors.New("状态无法改变")
	}
	tx,_:= model.PgSql.Begin()
	//时间
	thisTime := time.Now().Format(time.RFC3339)
	OrderChildUpdate := make(map[string]interface{})
	OrderChildUpdate["status"] = model.OrderChildByStatusFinish
	OrderChildUpdate["time_wait_finish"] = thisTime
	orderChildSqlUp, args := sql_aid.PgTable(model.TableByOrderChild).WhereId(input["order_child_id"]).UpdateByMap(&OrderChildUpdate)
	_, err = tx.Exec(orderChildSqlUp, args...)
	if err != nil {
		return errors.New("变更失败")
	}
	orderChildDiscussData := make(map[string]interface{})
	orderChildDiscussData["order_child_id"] = input["order_child_id"]
	orderChildDiscussData["user_id"] = userId
	orderChildDiscussData["shop_id"] = orderChildData[0]["shop_id"]
	orderChildDiscussData["goods_id"] = orderChildData[0]["goods_id"]
	orderChildDiscussData["goods_sku_id"] = orderChildData[0]["goods_sku_id"]
	orderChildDiscussData["content"] = input["content"]
	orderChildDiscussData["content_picture"] = input["content_picture"]
	orderChildDiscussData["star_grade"] = input["star_grade"]
	orderChildDiscussData["time_c"] = thisTime
	orderChildDiscussData["time_d"] = thisTime
	orderChildDiscussSql,args := sql_aid.PgTable(model.TableByOrderChildDiscuss).InsertByMap(&orderChildDiscussData)
	_,err = tx.Exec(orderChildDiscussSql,args...)
	if err != nil {
		return errors.New("插入数据失败")
	}
	tx.Commit()

	return nil
}





// OrderByPayBack 支付回调
func OrderByPayBack(orderId int64) error {
	//时间
	thisTime := time.Now().Format(time.RFC3339)
	orderSql, args := sql_aid.PgTable(model.TableByOrder).WhereId(orderId).ToSql()
	orderData, err := sql_aid.DataToMap(model.PgSql.Query(orderSql, args...))
	if err != nil {
		gogo_log.Error("server_OrderByPayBack", "订单查询失败", err.Error())
		return errors.New("回调失败")
	}
	if len(orderData) <= 0 {
		return errors.New("订单不存在")
	}

	tx, _ := model.PgSql.Begin()
	defer tx.Rollback()
	//更新主订单
	orderUpdate := make(map[string]interface{})
	orderUpdate["pay_type"] = 1
	orderUpdate["price_true"] = orderData[0]["price_all"]
	orderUpdate["price_time"] = thisTime
	orderUpdate["time_u"] = thisTime
	orderUpdateSql, args := sql_aid.PgTable(model.TableByOrder).WhereId(orderId).UpdateByMap(&orderUpdate)
	_, err = tx.Exec(orderUpdateSql, args...)
	if err != nil {
		gogo_log.Error("server_OrderByPayBack", "主订单操作失败", err.Error())
		return errors.New("主订单操作失败")
	}
	//更新子订单
	orderChildUpdate := make(map[string]interface{})
	orderChildUpdate["status"] = model.OrderChildByStatusSend //更改为代发货状态
	orderChildUpdate["time_wait_send"] = thisTime
	orderChildUpdateSql, args := sql_aid.PgTable(model.TableByOrderChild).Where(" order_id = ? ", orderId).UpdateByMap(&orderChildUpdate)
	_, err = tx.Exec(orderChildUpdateSql, args...)
	if err != nil {
		gogo_log.Error("server_OrderByPayBack", "子订单操作失败", err.Error())
		return errors.New("子订单操作失败")
	}
	tx.Commit()
	return nil
}
// OrderByPayChildBack 子订单支付回调
func OrderByPayChildBack(orderId int64)error{
	//时间
	thisTime := time.Now().Format(time.RFC3339)
	//更新子订单
	orderChildUpdate := make(map[string]interface{})
	orderChildUpdate["status"] = model.OrderChildByStatusSend //更改为代发货状态
	orderChildUpdate["time_wait_send"] = thisTime
	orderChildUpdateSql, args := sql_aid.PgTable(model.TableByOrderChild).WhereId(orderId).UpdateByMap(&orderChildUpdate)
	_, err := model.PgSql.Exec(orderChildUpdateSql, args...)
	if err != nil {
		gogo_log.Error("server_OrderByPayBack", "子订单操作失败", err.Error())
		return errors.New("子订单操作失败")
	}
	return nil

}
